/**
  * 文件说明
  * @Description:扩展说明
  * @Copyright: 2014 www.zhixueyun.com Inc. All right reserved
  * @Version: V6.0
  */
package com.frame.component.scheduled;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimerTask;


/**  
 * 定时器线程
 * 重复执行：每隔时间段执行、每日执行、每周执行、每月执行、每年执行
 * 执行一次：一定时间段后执行、某个时间点执行
 * @Author: liping.wang
 * @Date: 2014年4月18日 上午10:49:04 
 * @ModifyUser: liping.wang
 * @ModifyDate: 2014年4月18日 上午10:49:04 
 * @Version:V6.0
 */
public abstract class Schedule extends TimerTask implements Runnable {

	/**
	 * 
	 */
	private static final long DAY_MILLIS = 24 * 60 * 60 * 1000;
	/**
	 * 
	 */
	private static final long WEEK_MILLIS = 7 * DAY_MILLIS;
	/*
	 * 定时器类型
	 */
	public enum RepeatType {
		/*
		 * 执行一次
		 */
		Once,
		/*
		 * 在固定时间重复执行
		 */
		fixedForever,
		/*
		 * 在相对时间过后重复执行
		 */
		relativeForever
	};
	private String id;
	protected String name;
	protected RepeatType repeatType;  // 定时器类型
	protected long delay;             // 定时器延迟执行（第一次）,单位：毫秒
	protected long period;            // 定时器重复执行时间间隔，单位：毫秒
	private static final long minPeriod=1000; // 重复执行最小时间间隔，单位：毫秒
	/*
	 * 延迟执行一次
	 */
	public Schedule(long delay) {
		this.repeatType = RepeatType.Once;
		this.delay = delay<0 ?0 :delay;
		this.period = -1;
	}
	/*
	 * 在指定时间点执行一次
	 */
	public Schedule(Date time) {
		this(time.getTime() - System.currentTimeMillis());
	}
	/*
	 * 在延迟一段时间过后，定时重复执行
	 * @Param period  时间间隔，最小为1000ms
	 */
	public Schedule(long delay, long period) {
		this.repeatType = RepeatType.relativeForever;
		this.delay = delay<0 ?0 :delay;
		this.period = period<minPeriod ?minPeriod :period;
	}
	/*
	 * 重复在一天某个时间点执行
	 * @Param mmHHss  时间点，格式：HH:mm:ss
	 */
	public Schedule(String mmHHss) throws Exception {
		this.repeatType = RepeatType.relativeForever;
		this.period = DAY_MILLIS;

		long now = System.currentTimeMillis();
		String dateStr = DateUtil.formatDate(new Date(now), "yyyy-MM-dd")+" "+mmHHss;
		long delayRun = DateUtil.parseToDate(dateStr).getTime() - now;
		this.delay = delayRun>=0 ?delayRun :this.period+delayRun;
        this.delay = this.period;
	}
	
	/*
	 * 重复在一周中的某个时间点执行
	 * @Param whatDay 一周中的星期几：0-6
	 * @Param mmHHss  时间点，格式：HH:mm:ss
	 */
	public Schedule(int whatDay, String mmHHss) throws Exception {
		this.repeatType = RepeatType.relativeForever;
		this.period = WEEK_MILLIS;
		
		long now = System.currentTimeMillis();
		String dateStr = DateUtil.formatDate(new Date(now), "yyyy-MM-dd")+" "+mmHHss;
		long delayRun = DateUtil.parseToDate(dateStr).getTime()+(whatDay-DateUtil.weekDay(new Date(now)))*DAY_MILLIS - now;

		this.delay = delayRun>=0 ?delayRun :this.period+delayRun;
        this.delay = this.period;
	}
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	
}
